﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace GreetingCreatorGraphicUserControls.BackgroundAnimationCustomControl
{
    public class StoryboardFactory
    {
        public Storyboard CreateStoryboardAddItToGrid(UserControl item, Grid grid)
        {
            double yStopPosition = GetYStopPosition(grid);
            Duration duration = GetDuration(yStopPosition);

            DoubleAnimation doubleAnimationY = GetDoubleAnimationY(yStopPosition, duration);
            DoubleAnimation doubleAnimationAngle = GetDoubleAnimationAngle(duration);

            BuildStoryboardAnimation(doubleAnimationY, doubleAnimationAngle, item);

            Storyboard storyboard = CreateStoryboardAndAddAnimation(duration, doubleAnimationY, doubleAnimationAngle);
            SetStoryboardToGrid(item.Name, grid, storyboard);

            return (storyboard);
        }

        private DoubleAnimation GetDoubleAnimationAngle(Duration duration)
        {
            DoubleAnimation doubleAnimationAngle = CreateDoubleAnimation(duration);
            doubleAnimationAngle.To = RandomService.GetRandomAngle();
            return doubleAnimationAngle;
        }

        private DoubleAnimation GetDoubleAnimationY(double yStopPosition, Duration duration)
        {
            DoubleAnimation doubleAnimationY = CreateDoubleAnimation(duration);
            doubleAnimationY.To = yStopPosition;
            return doubleAnimationY;
        }

        private double GetYStopPosition(Grid grid)
        {
            const int extraMarginValue = 200;
            return grid.ActualHeight + extraMarginValue;
        }

        private Duration GetDuration(double yStopPosition)
        {
            int maxPixelSecund = Settings.MaxPixelSecund;
            int minPixelSecund = Settings.MinPixelSecund;

            double minDuration = yStopPosition/maxPixelSecund;
            double maxDuration = yStopPosition/minPixelSecund;
            return new Duration(TimeSpan.FromSeconds(RandomService.RandomDuration(minDuration, maxDuration)));
        }

        private void SetStoryboardToGrid(string name, Grid gridLayout, Storyboard storyboard)
        {
            gridLayout.Resources.Add(name, storyboard);
        }

        private DoubleAnimation CreateDoubleAnimation(Duration duration)
        {
            return new DoubleAnimation {Duration = duration};
        }

        private Storyboard CreateStoryboardAndAddAnimation(Duration duration, DoubleAnimation doubleAnimationY,
                                                           DoubleAnimation doubleAnimationAngle)
        {
            var sb = new Storyboard {Duration = duration};
            sb.Children.Add(doubleAnimationY);
            sb.Children.Add(doubleAnimationAngle);
            return sb;
        }

        private void BuildStoryboardAnimation(DoubleAnimation doubleAnimationY, DoubleAnimation doubleAnimationAngle,
                                              UserControl item)
        {
            int rotateTransFormindex = GetIndexOfTransFormType(item, typeof (RotateTransform));
            int translateFormindex = GetIndexOfTransFormType(item, typeof (TranslateTransform));

            string propertyPathForTranslateY = "(UIElement.RenderTransform).(TransformGroup.Children)[" +
                                               translateFormindex + "].(TranslateTransform.Y)";
            string propertyPathForTransformAngle = "(UIElement.RenderTransform).(TransformGroup.Children)[" +
                                                   rotateTransFormindex + "].(RotateTransform.Angle)";

            Storyboard.SetTarget(doubleAnimationY, item);
            Storyboard.SetTarget(doubleAnimationAngle, item);

            Storyboard.SetTargetProperty(doubleAnimationY, new PropertyPath(propertyPathForTranslateY));
            Storyboard.SetTargetProperty(doubleAnimationAngle, new PropertyPath(propertyPathForTransformAngle));
        }

        private int GetIndexOfTransFormType(UserControl item, Type transform)
        {
            int index = 0;
            foreach (Transform x in ((TransformGroup) item.RenderTransform).Children)
            {
                if (x.GetType() == transform)
                    return (index);

                index++;
            }
            return -1;
        }
    }
}